/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.network.miscellaneous.magnifier;

import java.awt.BorderLayout;
import java.awt.Color;
import java.util.List;

import twaver.Alarm;
import twaver.AlarmSeverity;
import twaver.Element;
import twaver.Link;
import twaver.Node;
import twaver.TDataBox;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.TaskAdapter;
import twaver.TaskScheduler;
import twaver.network.TNetwork;
import demo.DemoPane;

public class MagnifierDemo extends DemoPane {

	private TDataBox box;
	private TNetwork network;
	private Color labelColor = new Color(244, 244, 244);
	private Color messageBackground = new Color(244, 244, 244, 178);
	
	public MagnifierDemo() {
		this.network = new MagnifierNetwork();
		this.box = network.getDataBox();		
		this.initDataBox();
		this.add(network, BorderLayout.CENTER);
		this.registerAlarmGenerator();
		this.registerLinkMessageGenerator();
		this.registerServerHealthGenerator();
	}

	private void initDataBox() {
		final Node center = createNode();
		center.putLabelColor(labelColor);
		center.setImage("/demo/network/miscellaneous/magnifier/center.png");
		box.addElement(center);
		for (int i = 0; i < 7; i++) {
			Node node = createNode();
			node.putLabelColor(labelColor);
			box.addElement(node);
			node.addAttachment(ServerAttachment.class.getName());
			node.putAttachmentPosition(TWaverConst.POSITION_RIGHT);
			Link link = createLink(center, node);
			box.addElement(link);
		}
		network.setConsiderAttachmentOnLayout(true);
		network.doLayout(TWaverConst.LAYOUT_SYMMETRIC);
	}

	private void registerAlarmGenerator() {
		TaskScheduler.getInstance().register(new TaskAdapter() {
			int counter = 0;

			public void run(long clock) {
				if (counter > 10) {
					box.getAlarmModel().clear();
					counter = 0;
				} else {
					Element element = box.getRandomElement();
					AlarmSeverity severity = TWaverUtil.getRandomSeverity();

					Alarm alarm = new Alarm(TWaverUtil.valueOf(counter++),
							element.getID(), severity);
					box.getAlarmModel().addAlarm(alarm);
				}
			}

			public boolean interested() {
				return MagnifierDemo.this.isShowing();
			}

			public int getInterval() {
				return 5000;
			}
		});
	}

	private void registerServerHealthGenerator() {
		TaskScheduler.getInstance().register(new TaskAdapter() {
			public void run(long clock) {
				List nodes = box.getElementsByType(Node.class);
				for (int i = 0; i < nodes.size(); i++) {
					Node node = ((Node) nodes.get(i));
					double cpu = 0, memory = 0, traffic = 0;
					Object cpuValue = node.getClientProperty("cpu");
					if (cpuValue != null && cpuValue instanceof Double) {
						cpu = ((Double) cpuValue).doubleValue();
					}
					Object memoryValue = node.getClientProperty("memory");
					if (memoryValue != null && memoryValue instanceof Double) {
						memory = ((Double) memoryValue).doubleValue();
					}
					Object trafficValue = node.getClientProperty("traffic");
					if (trafficValue != null && trafficValue instanceof Double) {
						traffic = ((Double) trafficValue).doubleValue();
					}
					cpu += 10 * (TWaverUtil.getRandomDouble() - 0.5);
					if (cpu < 10) {
						cpu = 10;
					} else if (cpu > 100) {
						cpu = 100;
					}
					node.putClientProperty("cpu", new Double(cpu));
					memory += 10 * (TWaverUtil.getRandomDouble() - 0.5);
					if (memory < 10) {
						memory = 10;
					} else if (memory > 100) {
						memory = 100;
					}
					node.putClientProperty("memory", new Double(memory));
					traffic += 10 * (TWaverUtil.getRandomDouble() - 0.5);
					if (traffic < 10) {
						traffic = 10;
					} else if (traffic > 100) {
						traffic = 100;
					}
					node.putClientProperty("traffic", new Double(traffic));
				}
			}

			public boolean interested() {
				return MagnifierDemo.this.isShowing();
			}

			public int getInterval() {
				return 1000;
			}
		});
	}

	private void registerLinkMessageGenerator() {
		TaskScheduler.getInstance().register(new TaskAdapter() {
			public void run(long clock) {
				List nodes = box.getElementsByType(Link.class);
				for (int i = 0; i < nodes.size(); i++) {
					Link link = ((Link) nodes.get(i));
					int lose = TWaverUtil.getRandomInt(5);
					String string;
					if (TWaverUtil.getRandomInt(5) < 3) {
						link.putMessageContent(null);
					} else {
						if (lose > 2) {
							string = "<p color=red>PLR - " + lose + "pps</p>";
						} else {
							string = "PLR - " + lose + "pps<br>";
						}
						link.putMessageContent("<html>" + "AF - "
								+ TWaverUtil.getRandomInt(1000) + "bps<br>"
								+ "TF - "
								+ (1000 + TWaverUtil.getRandomInt(1000))
								+ "bps<br>" + "PER - "
								+ TWaverUtil.getRandomInt(10) + "kpps<br>"
								+ string + "</html>");
					}
				}
			}

			public boolean interested() {
				return MagnifierDemo.this.isShowing();
			}

			public int getInterval() {
				return 5000;
			}
		});
	}

	private Link createLink(Node center, Node node) {
		Link link = new Link(center, node);
		link.putLabelColor(labelColor);
		link.putLinkWidth(5);
		link.putLinkAntialias(true);
		link.putLink3D(true);
		link.putLinkColor(Color.GREEN);
		link.putMessagePosition(TWaverConst.POSITION_HOTSPOT);
		link.putMessageMinimizable(true);
		link.putMessageArc(8);
		link.putMessageBackground(messageBackground);
		link.addAttachment(TWaverConst.ATTACHMENT_MESSAGE);
		return link;
	}

	private Node createNode() {
		Node node = new Node();
		node.setImage("/demo/network/miscellaneous/magnifier/server.png");
		node.setName(TWaverUtil.getRandomInt(255) + "."
				+ TWaverUtil.getRandomInt(255) + "."
				+ TWaverUtil.getRandomInt(255) + "."
				+ TWaverUtil.getRandomInt(255));
		node.putClientProperty("cpu", new Double(50));
		node.putClientProperty("memory", new Double(50));
		node.putClientProperty("traffic", new Double(50));
		return node;
	}
}